import re

sendHeadStr = "<T"
replyHeadStr = "<F"
endStr = ">"

patternReply = re.compile(r'(?P<first><F[0-9,a-f,A-F]{16,16}>)(?P<last>.*)') #回传的命令正则表达式
patternSend  = re.compile(r'<T[0-9,a-f,A-F]{16,16}>') #发送的命令正则表达式

class rgblink_cmd:
	def __init__(self, adr = 0, sn = 0, cmd = 0, data1 = 0, data2 = 0, data3 = 0, data4 = 0, block = bytes()):
		self.sn = sn%256
		self.adr = adr%256
		self.cmd = cmd%256
		self.data = [data1%256, data2%256, data3%256, data4%256]
		self.block = block
	def __str__(self):
		return "cmd:{:02X},dat1:{:02X},dat2:{:02X},dat3:{:02X},dat4:{:02X}".format(self.cmd,self.data[0],self.data[1],self.data[2],self.data[3])
	def toSendString(self):
		checksum = self.sn+self.adr+self.cmd+self.data[0]+self.data[1]+self.data[2]+self.data[3]
		checksum &= 0xff
		tempStr = '{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}'.format(
			self.adr, self.sn, self.cmd,
			self.data[0], self.data[1], self.data[2],self.data[3],
			checksum)
		return sendHeadStr+tempStr+endStr
		
	def toReplyString(self):
		checksum = self.sn+self.adr+self.cmd+self.data[0]+self.data[1]+self.data[2]+self.data[3]
		tempStr = '{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}'.format(
			self.adr, self.sn, self.cmd,
			self.data[0], self.data[1], self.data[2],self.data[3],
			checksum)
		return replyHeadStr+tempStr+endStr
		
	def toSendBytes(self):
		return bytes(self.toSendString(), 'ascii') 
		
	def toReplyBytes(self):
		return bytes(self.toReplyString(), 'ascii') 
	
	def fromReplyString(cmdString):
		
		m = patternReply.search(str(cmdString))
		if m:
			tempBytes = m.group(0)[2:-1]
			cmd = rgblink_cmd()
			cmd.adr = int(tempBytes[0:2], 16)
			cmd.sn = int(tempBytes[2:4], 16)
			cmd.cmd = int(tempBytes[4:6], 16)
			cmd.data[0] = int(tempBytes[6:8], 16)
			cmd.data[1] = int(tempBytes[8:10], 16)
			cmd.data[2] = int(tempBytes[10:12], 16)
			cmd.data[3] = int(tempBytes[12:14], 16)			
			checksum = int(tempBytes[14:16], 16)
			sum = cmd.adr+cmd.sn+cmd.cmd+cmd.data[0]+cmd.data[1]+cmd.data[2]+cmd.data[3]
			if (sum%256) == checksum:				
				return cmd
			else:
				print("fromReplyString checksum 0x{0:02x}".format(sum%256) ,' error:' + str(cmdString))
				return None
		else:
			return None
	def fromReplyBytes(cmdBytes):
		for i in range(0, len(cmdBytes)-18):
			#print(i)
			if(cmdBytes[i] == ord(b'<')) and (cmdBytes[i+18] == ord(b'>')):
				#print(i)
				cmdBytes = cmdBytes[i:]
				break
		cmd = rgblink_cmd.fromReplyString(cmdBytes)
		if(cmd == None):
			return None
		cmd.block = cmdBytes[19:]
		return cmd
	def fromSendString(cmdString):
		m = patternSend.search(str(cmdString))
		if m:
			tempBytes = m.group(0)[2:-1]
			cmd = rgblink_cmd()
			cmd.adr = int(tempBytes[0:2], 16)
			cmd.sn = int(tempBytes[2:4], 16)
			cmd.cmd = int(tempBytes[4:6], 16)
			cmd.data[0] = int(tempBytes[6:8], 16)
			cmd.data[1] = int(tempBytes[8:10], 16)
			cmd.data[2] = int(tempBytes[10:12], 16)
			cmd.data[3] = int(tempBytes[12:14], 16)
			checksum = int(tempBytes[14:16], 16)
			sum = cmd.adr+cmd.sn+cmd.cmd+cmd.data[0]+cmd.data[1]+cmd.data[2]+cmd.data[3]
			if (sum%256) == checksum:				
				return cmd
			else:
				print("fromSendString checksum 0x{0:02x}".format(sum%256) ,' error:' + str(cmdString))
				return None
		else:
			return None
			
	def dataWord(self, index):
		if index > 3:
			return 0
		result = self.data[index]+(self.data[index+1]<<8)
		return result
	def dataRWord(self, index):
		if index > 3:
			return 0
		result = self.data[index+1]+(self.data[index]<<8)
		return result
	

#return "cmd:0x{02X},dat1:0x{02X},dat2:0x{02X},dat3:0x{02X},dat4:0x{02X}".format(self.cmd,self.data[0],self.data[1],self.data[2],self.data[3])
        

if __name__ == "__main__":
		
	cmd = rgblink_cmd(sn=1, cmd=0x68, data1 = 1)
	print(cmd.toSendString())
	print(cmd.toReplyString())
	m = patternReply.search("<F00006801321001ac>192192832948398")
	print(m.group(0))
	print(m.group(1))
	print(m.group(2))
	temp = rgblink_cmd.fromReplyBytes(b'\n\n~~~~\x80\x07\xc0\x03\x80\x07\x00\x058\x04\x10\x028\x04\xd0\x02\x1b8\x1b"<F0004f10a041d0020>\n\n\n\n~~~~\x80\x07\xc0\x03\x80\x07\x00\x058\x04\x10\x028\x04\xd0\x02\x1b8\x1b"\xe2')
	if temp:
		print(temp.toReplyString())
		print('device type = 0x{:04X}'.format(temp.dataRWord(1)))
		print("block:")
		print(temp.block, len(temp.block))
		      
	
	temp1 = rgblink_cmd.fromSendString("<T0000680100000069>")
	if temp1:
		print(temp1.toSendString())
		print(temp1)
		print(temp1.block)

